#include "TCPClient.h"
#include "../ZPL.h"
#include "../NL.h"
#include "NLData.h"
#include <pthread.h>
#include <string>
#include <list>

CTCPClient::CTCPClient() : CNetwork()
{
    m_nPort = 5050;
}

CTCPClient::~CTCPClient()
{

}

bool CTCPClient::Init()
{
    m_socketServer = socket(AF_INET, SOCK_STREAM, 0);
    if(m_socketServer < 0)
    {
        return false;
    }
    printf("TCP Client create socket success\n");

    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(m_nPort);
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    bzero(server.sin_zero, sizeof(server.sin_zero));

    int ret = connect(m_socketServer, (struct sockaddr*)&server, sizeof(struct sockaddr));
    if(ret < 0)
    {
        close(m_socketServer);
        return false;
    }
    printf("TCP Client connect success\n");

    return true;
}

bool CTCPClient::Run()
{
    return true;
}

bool CTCPClient::SendData(char* pData, int nLen)
{
    list<string> fsPackages;

    int nXALen = strlen(FS_XA);
    int nXZLen = strlen(FS_XZ);
    if(!GetFSPackage(pData + nXALen , nLen - nXALen - nXZLen, fsPackages))
    {
        printf("Error SendData: GetFSPackage");
        return false;
    }

    bool bSend = false;
    CNLData nlData;
    if(fsPackages.size() > 0)
    {
        vector<char> vNLPackage;
        nlData.TranslateStart(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }

    for(auto it = fsPackages.begin(); it != fsPackages.end(); it++)
    {
        if(nlData.AddPackageData(*it))
        {
        }
    }

    // 发送设置文本
    if(nlData.m_listTextData.size() > 0)
    {
        vector<char> vNLPackage;
        nlData.TranslateTextData(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            bSend = true;
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }

    // 发送文本内容
    if(nlData.m_listTextData.size() > 0)
    {
        vector<char> vNLPackage;
        nlData.TranslateTextContext(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            bSend = true;
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }

    // 发送设置条码
    if(nlData.m_listBarcodeData.size() > 0)
    {
        vector<char> vNLPackage;
        nlData.TranslateBarcodeData(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }

    // 发送条码内容
    if(nlData.m_listBarcodeData.size() > 0)
    {
        vector<char> vNLPackage;
        nlData.TranslateBarcodeContext(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }
    
    // 发送打印命令
    if(bSend)
    {
        vector<char> vNLPackage;
        nlData.TranslatePrint(vNLPackage);
        if(SendPackage(vNLPackage))
        {
            vector<char> vNLRevPackage;
            do{
                vNLRevPackage.clear();
                if(!GetPackage(vNLRevPackage))
                {
                    continue;
                }
            }
            while(!AcceptCommond(vNLRevPackage));
        }
    }
    return bSend;
}

bool CTCPClient::SendPackage(vector<char>& vNLPackage)
{
    bool bSend = false;
    if(vNLPackage.size() > 0)
    {
        string strCheckSum = CheckSum(vNLPackage);
        // 1字节<STX>    数据部分    2字节校验码    1字节<CR>    1字节保留 
        char* pSendData = new char[1 + vNLPackage.size() + 2 + 1 + 1];
        pSendData[0] = Code_STX;
        for(int i = 0; i < vNLPackage.size(); i++)
        {
            pSendData[i + 1] = vNLPackage[i];
        }
        // 校验码
        if(strCheckSum.size() < 2)
        {
            printf("check sum ff \n");
            strCheckSum = "FF";
        }
        pSendData[1 + vNLPackage.size() + 0] = 0x3F; //strCheckSum.at(0);
        pSendData[1 + vNLPackage.size() + 1] = 0x3F; //strCheckSum.at(1);
        pSendData[1 + vNLPackage.size() + 2] = Code_CR;
        pSendData[1 + vNLPackage.size() + 3] = 0;

        ssize_t s = send(m_socketServer, pSendData, 1 + vNLPackage.size() + 2 + 1, 0);
        if(s > 0)
        {
            bSend = true;
        }
        delete[] pSendData;
    }
    return bSend;
}

bool CTCPClient::GetPackage(vector<char>& vNLPackage)
{
    bool bPackageHeader = false;
    bool bPackageEnd = false;
    char byETB = Code_CR;
    do
    {
        // 将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度
        char arrRecData[2] = { 0x00, 0x00 };
        int length = recv(m_socketServer, arrRecData, 1, 0);
        if (length == 1)
        {
            if (!bPackageHeader)
            {
                if (arrRecData[0] == Code_SOH)
                {
                    byETB = Code_CR;
                    bPackageHeader = true;
                    continue;
                }
                if (arrRecData[0] == Code_SOH_S)
                {
                    byETB = Code_CR_S;
                    bPackageHeader = true;
                    continue;
                }
            }

            if (bPackageHeader)
            {
                if (arrRecData[0] == byETB)
                {
                    bPackageEnd = true;
                    break;
                }

                if (!bPackageEnd)
                {
                    vNLPackage.push_back(arrRecData[0]);
                }
            }
        }
        else
        {
            break;
        }
    } while (true);

    if (bPackageHeader && bPackageEnd)
    {
        return true;
    }

    return false;
}

bool CTCPClient::AcceptCommond(vector<char>& vNLPackage)
{
    bool bAccept = false;
    int nPackageSize = (int)vNLPackage.size();
    if (nPackageSize < 4)
    {
        return bAccept;
    }

    char* pData = new char[nPackageSize]; // 创建数组，大小为list的大小
    if (pData == nullptr)
    {
        return bAccept;
    }
    std::copy(vNLPackage.begin(), vNLPackage.end(), pData); // 将list的元素复制到数组中

    // 打印机id
    char nId = pData[0];
    char szCmd = pData[1];
    switch (szCmd)
    {
    case 'A':
        printf("printer A command\n");
        bAccept = true;
    case 'E':
        printf("printer E command\n");
        bAccept = true;
    case 'D':
        printf("printer D command\n");
        bAccept = true;
    case '0':
        printf("printer status command\n");
        break;
    default:
        break;
    }
    delete pData;

    return bAccept;
}

bool CTCPClient::GetFSPackage(char* pData, int nLen, list<string>& fsPackages)
{
    if(pData == nullptr || nLen <= 0)
    {
        return false;
    }
    string strData(pData, nLen);
    strData = trim(strData);
    fsPackages.clear();

    int nStart = 0;
    int nEnd = strData.find(FC_FS);
    while(nEnd > 0)
    {
        if(nEnd > nStart)
        {
            string strPackage = strData.substr(nStart, nEnd - nStart);
            strPackage = trim(strPackage);
            if(strPackage.size() > 0)
            {
                fsPackages.push_back(strPackage);
            }
        }
        nStart = nEnd + strlen(FC_FS);
        nEnd = strData.find(FC_FS, nStart);
    }
    if(nStart < strData.length())
    {
        fsPackages.push_back(strData.substr(nStart));
    }

    /// fsPackages
    printf("fsPackages: start\n");
    for(auto it = fsPackages.begin(); it != fsPackages.end(); it++)
    {
        printf("%s\n", (*it).c_str());
    }
    printf("fsPackages: end\n");

    if(fsPackages.size() > 0)
    {
        return true;
    }

    return false;
}